#include <gulcolor.h>
#include <eikenv.h>
#include <S32STOR.H>
#include <s32file.h>
#include <centralrepository.h>
#include <ProfileEngineSDKCRKeys.h>
#include <APGCLI.H>

#include "Utils.h"
#include "AppUi.h"
#include "Application.h"

#include <hal.h> // also link to hal.lib
#include "Logger.h"

Utils::TDevice Utils::GetDevice()
{
	TInt deviceUid;
	HAL::Get( HALData::EMachineUid, deviceUid );
	LOG_FORMAT( _L("deviceUid: 0x%08x"), deviceUid );
	if( deviceUid == 0x2000DA56 )
		return ENokia5800XpressMusic;
	else if( deviceUid == 0x2001DE9D || deviceUid == 0x2001DE9E )
		return ENokia5530XpressMusic;
	else if( deviceUid == 0x20023763 || deviceUid == 0x20023764 )
		return ENokia5230;
	else if( deviceUid == 0x2000DA54 )
		return ENokia6210Navigator;
	else if( deviceUid == 0x200005F9 )
		return ENokiaN80;
	else if( deviceUid == 0x200005FB )
		return ENokiaN73;
	else if( deviceUid == 0x2000060B )
		return ENokiaN95;
	else if( deviceUid == 0x20014DDD || deviceUid == 0x20014DDE || deviceUid == 0x20023766 )
		return ENokiaN97;
	else if( deviceUid == 0x2000C520 )
		return ESamsungGTi8910;
	else
		return EOther;
}

void Utils::StartExeL(TUid aAppUid)
{
	RApaLsSession lsSession;
	lsSession.Connect();
	CleanupClosePushL(lsSession);//+lsSession
	TApaAppInfo appInfo;
	TInt err = lsSession.GetAppInfo(appInfo, aAppUid);
	CApaCommandLine *cmd = CApaCommandLine::NewLC();//+cmd
	cmd->SetExecutableNameL(appInfo.iFullName);
	cmd->SetCommandL(EApaCommandRun); 
	err = lsSession.StartApp(*cmd);
	User::LeaveIfError(err);
	CleanupStack::PopAndDestroy(2);//-cmd, lsSession
}

CDesCArrayFlat* Utils::FileListLC(const TDesC& aPath)
{
	CDesCArrayFlat* fileList =  new (ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL(fileList);//+fileList

	RFs& fs (CEikonEnv::Static()->FsSession());
	CDir* dirList;
	if (KErrNone == fs.GetDir(aPath, KEntryAttDir, EDirsFirst|ESortByName, dirList))
	{//error reading the folder
		CleanupStack::PushL(dirList);//+dirList

		for (TInt i=0; i<dirList->Count();i++)
		{
			fileList->AppendL(dirList->operator[](i).iName);
		}

		CleanupStack::PopAndDestroy();//-dirList
	}
	return fileList;
}

void Utils::FileListL(const TDesC& aPath, MFileListObserver* aObserver)
{
	RFs& fs (CEikonEnv::Static()->FsSession());
	CDir* dirList;
	if (KErrNone == fs.GetDir(aPath, KEntryAttDir, EDescending|ESortByDate, dirList))
	{//error reading the folder
		CleanupStack::PushL(dirList);//+dirList

		for (TInt i=0; i<dirList->Count();i++)
		{ 
			TEntry entry = dirList->operator[](i);
			if (entry.IsDir())
			{
				TFileName path = aPath;
				path.Append(entry.iName);
				path.Append(_L("\\"));
				FileListL(path, aObserver);
			}
			else
			{
				aObserver->AddStringL(entry, aPath);
			}
		}

		CleanupStack::PopAndDestroy();//-dirList
	}
}

TInt Utils::FilesCountL(const TDesC& aPath)
{
	RFs& fs (CEikonEnv::Static()->FsSession());
	CDir* dirList = NULL;
	TInt filesCount = 0;
	if (KErrNone == fs.GetDir(aPath, KEntryAttDir, EDirsFirst|ESortByName, dirList))
	{
		filesCount = dirList->Count();
		delete dirList;
	}
	return filesCount;
}

TDes& Utils::GetR(TInt aResId)
{
	DefAppUi;
	return appUi->GetR(aResId);
}

void Utils::SaveIntL(const TInt aKey, const TInt aValue)
{
	CDictionaryStore* iniFile = CDictionaryFileStore::OpenLC(CCoeEnv::Static()->FsSession(), KSettingsFileName, KUidMyApp);
	//+iniFile
	Utils::SaveIntL(iniFile, aKey, aValue);
	CleanupStack::PopAndDestroy();//-iniFile				
}

void Utils::LoadIntL(const TInt aKey, TInt& aValue, TInt aDefaultValue)
{
	CDictionaryStore* iniFile = CDictionaryFileStore::OpenLC(CCoeEnv::Static()->FsSession(), KSettingsFileName, KUidMyApp);
	//+iniFile
	Utils::LoadIntL(iniFile, aKey, aValue, aDefaultValue);
	CleanupStack::PopAndDestroy();//-iniFile
}

void Utils::SaveIntArrayL( CDictionaryStore* aIniFile, TInt aKey, const TArray< TInt >& aArray)
{
	RDictionaryWriteStream stream;
	
	stream.AssignLC(*aIniFile, TUid::Uid(aKey));//+stream
	stream.WriteInt16L( aArray.Count() );

	for (TInt i = 0;i < aArray.Count();i++)
	{
		stream.WriteUint32L(aArray[i]);
	}
	stream.CommitL();
	CleanupStack::PopAndDestroy(); //-stream
	aIniFile->CommitL();
}

void Utils::LoadIntArrayL( CDictionaryStore* aIniFile, TInt aKey, RArray< TInt >& aArray )
{
	TUid uid = TUid::Uid(aKey);
	if (aIniFile->IsPresentL(uid))
	{
		aArray.Reset();

		RDictionaryReadStream stream;
		stream.OpenLC(*aIniFile, uid);//+stream

		TInt count = stream.ReadInt16L();
		for( TInt i = 0;i < count; i++)
		{
			aArray.Append( stream.ReadUint32L() );
		}

		CleanupStack::PopAndDestroy();//-stream
	}
}


